package one.stand.controller.order;

import cn.hutool.core.date.DateUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jmp.api.dto.*;
import com.jmp.autocofiguration.web.interceptor.SecurityAuthCheck;
import com.jmp.base.dto.*;
import com.jmp.feign.AddressFeign;
import com.jmp.feign.CompanyFeign;
import com.jmp.feign.OrderFeign;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import one.stand.advice.ResultEnum;
import one.stand.dto.Company2Dto;
import one.stand.dto.ConvertUtils;
import one.stand.dto.PageResponse2;
import one.stand.enums.OrderStateEnum;
import one.stand.enums.RefundStateEnum;
import one.stand.mapper.GoodSpecMapperExt;
import one.stand.model.BusinessCard;
import one.stand.model.GoodSpec;
import one.stand.model.Goods;
import one.stand.model.ResultModel;
import one.stand.service.BusinessCardBaseService;
import one.stand.service.CompanyBaseService;
import one.stand.service.GoodsBaseService;
import one.stand.service.GoodsPhotoService;
import one.stand.util.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author cjr
 */
@Api(description = "订单管理")
@RestController
@RequestMapping("order")
public class OrderController {
    @Autowired
    private AddressFeign addressFeign;
    @Autowired
    private OrderFeign orderFeign;
    @Autowired
    private CompanyFeign companyFeign;

    @Autowired
    private GoodsBaseService goodsBaseService;
    @Autowired
    private GoodsPhotoService goodsPhotoService;
    @Autowired
    private GoodSpecMapperExt goodSpecMapperExt;
    @Autowired
    private CompanyBaseService companyBaseService;
    @Autowired
    private BusinessCardBaseService businessCardBaseService;

    @ApiOperation(value = "1确认订单")
    @GetMapping("confirm")
    @SecurityAuthCheck
    public ResultModel<OrderConfirmResponse> confirm(@RequestAttribute OrderConfirmRequest request) {
        AssertUtil.nonNull(request.getGoodsList(), ResultEnum.PARAM_CHECK, "请选择商品");

        final RequestContext.User optUser = RequestContextHolder.getRequestContext().getUser();

        ResultModel<AddressDefaultVo> resultModel = addressFeign.default1(AddressDefaultDto.builder().userId(optUser.getUserId()).build());
        AssertUtil.isTrue(resultModel);
        OrderConfirmResponse.Address address = null;
        if (Objects.nonNull(resultModel.getData())) {
            address = OrderConfirmResponse.Address.builder()
                    .addressId(resultModel.getData().getAddressId())
                    .receiveName(resultModel.getData().getReceiveName())
                    .receivePhone(resultModel.getData().getReceivePhone())
                    .address(resultModel.getData().getLocationAddress() + resultModel.getData().getDetailedAddress())
                    .build();
        }

        Integer total = 0;
        BigDecimal totalPrice = BigDecimal.ZERO;
        Map<Integer, OrderConfirmResponse.Supplier> map = Maps.newLinkedHashMap();
        GoodSpec goodSpec;
        Goods goods;
        OrderConfirmResponse.Goods goodsResult;
        BigDecimal price;
        Company2Dto company2Dto;
        for (OrderConfirmRequest.Goods spec : request.getGoodsList()) {
            goodSpec = goodSpecMapperExt.selectByPrimaryKey(spec.getSpecId());
            AssertUtil.nonNull(goodSpec, ResultEnum.PARAM_CHECK, "商品不存在");
            AssertUtil.isTrue(goodSpec.getIsDel() == 0, ResultEnum.PARAM_CHECK, "商品不存在");
            AssertUtil.isTrue(goodSpec.getPrice() >= 0, ResultEnum.PARAM_CHECK, "商品不可交易");
            AssertUtil.isTrue(goodSpec.getSpecNum() >= spec.getNum(), ResultEnum.PARAM_CHECK, "商品库存不足");
            goods = goodsBaseService.get(goodSpec.getGoodsId());
            AssertUtil.nonNull(goods, ResultEnum.PARAM_CHECK, "商品不存在");
            AssertUtil.isTrue(goods.getIsDel() == 0, ResultEnum.PARAM_CHECK, "商品不存在");
            AssertUtil.isTrue(goods.getIsPayment() == 1, ResultEnum.PARAM_CHECK, "商品不可交易");
            goodsResult = OrderConfirmResponse.Goods.builder()
                    .shopChatId(spec.getShopChatId())
                    .goodsId(goods.getGoodsId())
                    .goodsSpecId(spec.getSpecId())
                    .specName(goodSpec.getSpecAttribute() + " " + goodSpec.getSpecName())
                    .name(goods.getGoodsName())
                    .photo(OneStringUtils.photoResize(goodsPhotoService.getPath(goods.getGoodsId())))
                    .num(spec.getNum())
                    .price(MoneyUtil.getMoney(goodSpec.getPrice()).multiply(BigDecimal.valueOf(spec.getNum())))
                    .groupId(spec.getGroupId())
                    .build();
            total = total + spec.getNum();
            price = MoneyUtil.getMoney(goodSpec.getPrice()).multiply(BigDecimal.valueOf(spec.getNum()));
            totalPrice = totalPrice.add(price);

//            if(Objects.nonNull(optUser.getCompanyId())) {
//                AssertUtil.isTrue(optUser.getCompanyId().equals(goods.getCompanyId()), ResultEnum.PARAM_CHECK);
//            }

            if (map.containsKey(goods.getCompanyId())) {
                map.get(goods.getCompanyId()).getGoodsList().add(goodsResult);
                map.get(goods.getCompanyId()).setTotalPrice(map.get(goods.getCompanyId()).getTotalPrice().add(price));
            } else {
                company2Dto = companyBaseService.get2(goods.getCompanyId());
                map.put(goods.getCompanyId(), OrderConfirmResponse.Supplier.builder()
                        .companyId(company2Dto.getCompanyId())
                        .companyName(company2Dto.getCompanyName())
                        .companyLogo(company2Dto.getCompanyLogo())
                        .totalPrice(price)
                        .goodsList(Lists.newArrayList(goodsResult))
                        .build());
            }
        }

        List<OrderConfirmResponse.Supplier> supplierList = Lists.newArrayList(map.values());

        OrderConfirmResponse response = OrderConfirmResponse.builder()
                .address(address)
                .supplierList(supplierList)
                .total(total)
                .totalPrice(totalPrice)
                .build();
        return ResultModel.success(response);
    }

    @ApiOperation(value = "2保存订单")
    @PostMapping("save")
    @SecurityAuthCheck
    public ResultModel<OrderSaveResponse> save(@RequestAttribute OrderSaveRequest request) {
        final RequestContext.User optUser = RequestContextHolder.getRequestContext().getUser();

        ResultModel<OrderSaveVo> resultModel = orderFeign.save(OrderSaveDto.builder()
                .checkFlag(true)
                .userId(optUser.getUserId())
                .addressId(request.getAddressId())
                .total(request.getTotal())
                .totalPrice(request.getTotalPrice())
                .supplierList(ConvertUtils.list(request.getSupplierList(), supplier -> {
                    return OrderSaveDto.Supplier.builder()//订单
                            .companyId(supplier.getCompanyId())
                            .totalPrice(supplier.getTotalPrice())
                            .remark(supplier.getRemark())
                            .goodsList(ConvertUtils.list(supplier.getGoodsList(), goods -> {
                                return OrderSaveDto.Goods.builder()//商品
                                        .specId(goods.getGoodsSpecId())
                                        .num(goods.getNum())
                                        .shopCartId(goods.getShopChatId())
                                        .cardId(null)
                                        .forwardId(null)
                                        .groupId(goods.getGroupId())
                                        .build();
                            }))
                            .build();
                }))
                .build());
        AssertUtil.isTrue(resultModel);

        OrderSaveResponse response = OrderSaveResponse.builder()
                .orderIds(resultModel.getData().getOrderIds())
                .build();
        return ResultModel.success(response);
    }

    @ApiOperation(value = "3支付：微信")
    @PostMapping("pay/wx")
    @SecurityAuthCheck
    public ResultModel<OrderPayWxResponse> payWx(@RequestAttribute OrderPayRequest request) {
        final RequestContext.User optUser = RequestContextHolder.getRequestContext().getUser();

        ResultModel<OrderPayWxAppVo> resultModel = orderFeign.payWxApp(OrderPayWxAppDto.builder()
                .orderIds(request.getOrderIds())
                .optUserId(optUser.getUserId())
                .build());
        AssertUtil.isTrue(resultModel);

        OrderPayWxResponse response = OrderPayWxResponse.builder()
                .appid(resultModel.getData().getAppid())
                .partnerid(resultModel.getData().getPartnerid())
                .prepayid(resultModel.getData().getPrepayid())
                .packageStr(resultModel.getData().getPackageStr())
                .noncestr(resultModel.getData().getNoncestr())
                .timestamp(resultModel.getData().getTimestamp())
                .sign(resultModel.getData().getSign())
                .build();
        return ResultModel.success(response);
    }

    @ApiOperation(value = "3支付：支付宝")
    @PostMapping("pay/alipay")
    @SecurityAuthCheck
    public ResultModel<OrderPayAlipayResponse> payAlipay(@RequestAttribute OrderPayRequest request) {
        final RequestContext.User optUser = RequestContextHolder.getRequestContext().getUser();
        ResultModel<OrderPayWxAlipayVo> resultModel = orderFeign.payAlipay(OrderPayWxAlipayDto.builder()
                .orderIds(request.getOrderIds())
                .optUserId(optUser.getUserId())
                .build());
        AssertUtil.isTrue(resultModel);

        OrderPayAlipayResponse response = OrderPayAlipayResponse.builder()
                .orderInfo(resultModel.getData().getOrderInfo())
                .build();
        return ResultModel.success(response);
    }

    @ApiOperation(value = "4订单列表")
    @GetMapping("list")
    @SecurityAuthCheck
    public ResultModel<OrderListResponse> list(@RequestAttribute OrderListRequest request) {
        final RequestContext.User optUser = RequestContextHolder.getRequestContext().getUser();

        ResultModel<OrderListVo> resultModel = orderFeign.list(OrderListDto.builder()
                .userId(optUser.getUserId())
                .status(request.getStatus())
                .keyword(request.getKeyword())
                .build());
        AssertUtil.isTrue(resultModel);

        PageResponse2<OrderListResponse.Order> pageResponse2 = ConvertUtils.page2(resultModel.getData().getOrderPage(), order -> {
            Company2Dto company2Dto = companyBaseService.get2(order.getCompanyId());

            Integer type = null;
            if (order.getOrderState().equals(OrderStateEnum.WAIT_PAYMENT.getCode())) {
                type = 1;
            } else if (order.getRefundState().equals(RefundStateEnum.REFUND_APPLY.getCode())) {
                type = 6;
            } else if (order.getOrderState().equals(OrderStateEnum.WAIT_DELIVER.getCode())) {
                type = 2;
            } else if (order.getOrderState().equals(OrderStateEnum.WAIT_RECEIVING.getCode())) {
                type = 3;
            } else if (order.getOrderState().equals(OrderStateEnum.COMPLETE.getCode())) {
                type = 4;
            } else if (order.getOrderState().equals(OrderStateEnum.REFUND_SUCCESS.getCode())) {
                type = 7;
            } else if (order.getOrderState().equals(OrderStateEnum.CANCEL.getCode())
                    || order.getOrderState().equals(OrderStateEnum.BE_OVERDUE.getCode())) {
                type = 5;
            }
            return OrderListResponse.Order.builder()
                    .orderId(order.getOrderId())
                    .orderPrice(order.getOrderPrice())
                    .orderStatus(type)

                    .companyId(order.getCompanyId())
                    .companyLogo(company2Dto.getCompanyLogo())
                    .companyName(company2Dto.getCompanyName())

                    .cancelFlag(order.getCancelFlag())
                    .payFlag(order.getPayFlag())
                    .refundFlag(order.getRefundFlag())
                    .refundCancelFlag(order.getRefundCancelFlag())
                    .remindSendFlag(order.getRemindSendFlag())
                    .completeFlag(order.getCompleteFlag())

                    .goodsList(ConvertUtils.list(order.getGoodsList(), goods -> {
                        return OrderListResponse.Goods.builder()
                                .goodsId(goods.getGoodsId())
                                .goodsName(goods.getGoodsName())
                                .goodsPhoto(OneStringUtils.photoResize(goods.getGoodsPhoto()))
                                .skuName(goods.getSkuName())
                                .skuNum(goods.getSkuNum())
                                .price(goods.getPrice().multiply(BigDecimal.valueOf(goods.getSkuNum())))
                                .build();
                    }))

                    .build();
        });

        OrderListResponse response = OrderListResponse.builder()
                .orderPage(pageResponse2)
                .build();
        return ResultModel.success(response);
    }

    @ApiOperation(value = "5订单详情")
    @GetMapping("detail")
    @SecurityAuthCheck
    public ResultModel<OrderDetailResponse> detail(@RequestAttribute OrderDetailRequest request) {

        ResultModel<OrderDetailVo> resultModel = orderFeign.detail(OrderDetailDto.builder().orderId(request.getOrderId()).build());
        AssertUtil.isTrue(resultModel);

        OrderDetailVo vo = resultModel.getData();
        Company2Dto company2Dto = companyBaseService.get2(vo.getCompanyId());

        //企业名片
        ResultModel<CompanyCardResponse> cardResponseResultModel = companyFeign.card(CompanyCardRequest.builder().companyId(vo.getCompanyId()).build());
        Integer cardId = ConvertUtils.result(cardResponseResultModel, CompanyCardResponse::getCardId);
        String kfTel = StringUtils.EMPTY;
        String kfChatId = StringUtils.EMPTY;
        if (Objects.nonNull(cardId)) {
            BusinessCard businessCard = businessCardBaseService.getCustomer(cardId);
            if (Objects.nonNull(businessCard)) {
                kfChatId = String.valueOf(businessCard.getUserId());
                kfTel = businessCard.getPhone();
            }
        }

        String statusInfo = StringUtils.EMPTY;
        Integer type = null;
        if (vo.getOrderState().equals(OrderStateEnum.WAIT_PAYMENT.getCode())) {
            statusInfo = "等待买家支付（订单" + DateUtil.secondToTime(Math.toIntExact(vo.getPayTimeLeft())) + "后自动关闭）";
            type = 1;
        } else if (vo.getRefundState().equals(RefundStateEnum.REFUND_APPLY.getCode())) {
            statusInfo = "退款申请中（7天内卖家无响应自动退款）";
            type = 6;
        } else if (vo.getOrderState().equals(OrderStateEnum.WAIT_DELIVER.getCode())) {
            statusInfo = "等待发货";
            type = 2;
        } else if (vo.getOrderState().equals(OrderStateEnum.WAIT_RECEIVING.getCode())) {
            statusInfo = "卖家已发货";
            type = 3;
        } else if (vo.getOrderState().equals(OrderStateEnum.COMPLETE.getCode())) {
            statusInfo = "订单已完成";
            type = 4;
        } else if (vo.getOrderState().equals(OrderStateEnum.REFUND_SUCCESS.getCode())) {
            statusInfo = "退款已完成";
            type = 7;
        } else if (vo.getOrderState().equals(OrderStateEnum.CANCEL.getCode())
                || vo.getOrderState().equals(OrderStateEnum.BE_OVERDUE.getCode())) {
            statusInfo = "交易取消";
            type = 5;
        }

        String deliveryInfo = StringUtils.isNoneBlank(vo.getDeliveryCompany()) ? StringUtils.defaultIfBlank(vo.getDeliveryCompany(), StringUtils.EMPTY) + " " + StringUtils.defaultIfBlank(vo.getDeliveryNo(), StringUtils.EMPTY) : StringUtils.EMPTY;

        OrderDetailResponse response = OrderDetailResponse.builder()
                .orderId(vo.getOrderId())
                .orderStatusInfo(statusInfo)
                .orderStatus(type)
                .orderRemark(vo.getOrderRemark())
                .orderNo(vo.getOrderNo())
                .orderCreateTime(vo.getOrderCreateTime())
                .orderPayTime(vo.getOrderPayTime())
                .deliveryInfo(deliveryInfo)
                .refundRemark(vo.getRefundRemark())

                .addressName(vo.getAddressName())
                .addressPhone(vo.getAddressPhone())
                .addressDetail(vo.getAddressDetail())

                .companyId(vo.getCompanyId())
                .companyLogo(company2Dto.getCompanyLogo())
                .companyName(company2Dto.getCompanyName())
                .kfTel(kfTel)
                .kfChatId(kfChatId)

                .goodsList(ConvertUtils.list(vo.getGoodsList(), goods -> {
                    return OrderDetailResponse.Goods.builder()
                            .goodsId(goods.getGoodsId())
                            .goodsName(goods.getGoodsName())
                            .goodsPhoto(OneStringUtils.photoResize(goods.getGoodsPhoto()))
                            .skuName(goods.getSkuName())
                            .skuNum(goods.getSkuNum())
                            .price(goods.getPrice().multiply(BigDecimal.valueOf(goods.getSkuNum())))
                            .build();
                }))
                .build();
        return ResultModel.success(response);
    }

    @ApiOperation(value = "6订单取消")
    @PostMapping("cancel")
    @SecurityAuthCheck
    public ResultModel cancel(@RequestAttribute OrderCancelRequest request) {

        ResultModel resultModel = orderFeign.cancel(OrderCancelDto.builder().orderId(request.getOrderId()).build());
        AssertUtil.isTrue(resultModel);

        return ResultModel.success();
    }

    @ApiOperation(value = "6提醒发货")
    @PostMapping("remind/send")
    @SecurityAuthCheck
    public ResultModel remindSend(@RequestAttribute OrderCancelRequest request) {

        ResultModel resultModel = orderFeign.remindSend(OrderRemindSendDto.builder().orderId(request.getOrderId()).build());
        AssertUtil.isTrue(resultModel);

        return ResultModel.success();
    }

    @ApiOperation(value = "6确认收货")
    @PostMapping("complete")
    @SecurityAuthCheck
    public ResultModel complete(@RequestAttribute OrderCancelRequest request) {

        ResultModel resultModel = orderFeign.complete(OrderCancelDto.builder().orderId(request.getOrderId()).build());
        AssertUtil.isTrue(resultModel);

        return ResultModel.success();
    }

    @ApiOperation(value = "6退款申请")
    @PostMapping("refund/apply")
    @SecurityAuthCheck
    public ResultModel refundApply(@RequestAttribute OrderRefundApplyRequest request) {

        ResultModel resultModel = orderFeign.refundApply(OrderRefundApplyDto.builder()
                .orderId(request.getOrderId())
                .refundRemark(request.getRefundRemark())
                .build());
        AssertUtil.isTrue(resultModel);

        return ResultModel.success();
    }

    @ApiOperation(value = "6退款申请取消")
    @PostMapping("refund/cancel")
    @SecurityAuthCheck
    public ResultModel refundCancel(@RequestAttribute OrderCancelRequest request) {

        ResultModel resultModel = orderFeign.refundCancel(OrderRefundCancelDto.builder().orderId(request.getOrderId()).build());
        AssertUtil.isTrue(resultModel);

        return ResultModel.success();
    }
}
